#include "xd3d9HardBuffer.h"
#include "xLogManager.h"
#include "xD3D9Help.h"


namespace XE	
{

	xd3d9VertexBuffer::xd3d9VertexBuffer(UINT VertexCount,UINT VerteSize,LPDIRECT3DDEVICE9 pDevice,DWORD Usage )
		:xVertexHardBuffer(VertexCount,VerteSize),m_pDevice(pDevice	),m_pd3d9Buffer(NULL),m_Usage(Usage)
	{
		D3DPOOL pool = D3DPOOL_MANAGED;
		if(Usage&D3DUSAGE_DYNAMIC)
		{
         pool = D3DPOOL_DEFAULT;
		}

		if(FAILED(m_pDevice->CreateVertexBuffer(VertexCount*VerteSize,Usage,0,pool,&m_pd3d9Buffer,NULL)))
		{
			xLogMessager::getSingleton().logMessage("d3d9 Create VertexBuffer Fail");
			throw("d3d9 Create VertexBuffer fail");
		}

	}
	xd3d9VertexBuffer::~xd3d9VertexBuffer()
	{
		SafeRelease(m_pd3d9Buffer)

	}

	void* xd3d9VertexBuffer::Lock()
	{
		void* pBuff=NULL;
		if(m_pd3d9Buffer!=NULL)
		{
			if(m_Usage&D3DUSAGE_DYNAMIC)
			{
				m_pd3d9Buffer->Lock(0,0,&pBuff,D3DLOCK_DISCARD );
			}else
			{
				m_pd3d9Buffer->Lock(0,0,&pBuff,D3DLOCK_NOSYSLOCK );
			}
		}
		return pBuff;
	}

	void xd3d9VertexBuffer::UnLock()
	{
		if(m_pd3d9Buffer!=NULL)
			m_pd3d9Buffer->Unlock();
		return ;

	}


	HRESULT xd3d9VertexBuffer::Resize(UINT vertexCount)
	{
		SafeRelease(m_pd3d9Buffer)

			D3DPOOL pool = D3DPOOL_MANAGED;
		if(m_Usage&D3DUSAGE_DYNAMIC)
		{
			pool = D3DPOOL_DEFAULT;
		}


			if(FAILED(m_pDevice->CreateVertexBuffer(vertexCount*m_VertexSize,0,0,pool,&m_pd3d9Buffer,NULL)))
			{
				xLogMessager::getSingleton().logMessage("d3d9 Create VertexBuffer Fail");
				throw("d3d9 Create VertexBuffer fail");
			}

			m_vertexCount = vertexCount;
			m_size = m_VertexSize*m_vertexCount;

			return X_OK;
	}

	//bool xd3d9VertexBuffer::ReSize(UINT size) 
	//{
	//	if(m_size==size)
	//		return true;
	//	SafeRelease(m_pd3d9Buffer);


	//	return true;
	//}




	/*----------------------------------------------------------------------------------
	indexbuffer
	//------------------------------------------------------------------------------------*/

	xd3d9IndexBuffer::xd3d9IndexBuffer(UINT indexCount,xIndexHardBufferType indextype,LPDIRECT3DDEVICE9 pDevice,DWORD Usage)
		:xIndexHardBuffer(indexCount,indextype),m_pDevice(pDevice),m_pd3d9buffer(NULL),m_Usage(Usage)
	{

		assert(m_pDevice);
		D3DPOOL pool = D3DPOOL_MANAGED;
		if(Usage&D3DUSAGE_DYNAMIC)
		{
			pool = D3DPOOL_DEFAULT;
		}

		D3DFORMAT  format = indextype==IndexHardBufferType_16?D3DFMT_INDEX16:D3DFMT_INDEX32;
		if(FAILED(m_pDevice->CreateIndexBuffer(m_size,Usage,format,pool ,&m_pd3d9buffer,NULL)))
		{
			xLogMessager::getSingleton().logMessage("d3d9Create indexBuffer Fail");
			throw("d3d9Create indexBuffer Fail");
		}


	}

	xd3d9IndexBuffer::~xd3d9IndexBuffer()
	{
		SafeRelease(m_pd3d9buffer)

	}


	void* xd3d9IndexBuffer::Lock() 
	{


		void* pBuff=NULL;
		if(m_pd3d9buffer!=NULL)
		{
           if(m_Usage&D3DUSAGE_DYNAMIC)
		   {
			   m_pd3d9buffer->Lock(0,0,&pBuff,D3DLOCK_DISCARD );
		   }else
		   {
			   m_pd3d9buffer->Lock(0,0,&pBuff,D3DLOCK_NOSYSLOCK );
		   }
			
		}
		return pBuff;
	}

	void xd3d9IndexBuffer::UnLock()
	{
		if(m_pd3d9buffer!=NULL)
			m_pd3d9buffer->Unlock();

	}

	HRESULT xd3d9IndexBuffer::Resize(UINT indexCount)
	{
		SafeRelease(m_pd3d9buffer)
		D3DFORMAT  format = D3DFMT_INDEX16;
		UINT presize = 0;
		if(m_IndexType==IndexHardBufferType_16)
		{
			format = D3DFMT_INDEX16;
			presize = 16;
		}else
		{
			format = D3DFMT_INDEX32;
			presize = 32;
		}

		D3DPOOL pool = D3DPOOL_MANAGED;
		if(m_Usage&D3DUSAGE_DYNAMIC)
		{
			pool = D3DPOOL_DEFAULT;
		}


		if(FAILED(m_pDevice->CreateIndexBuffer(presize*indexCount,0,format,pool ,&m_pd3d9buffer,NULL)))
		{
			xLogMessager::getSingleton().logMessage("d3d9Create indexBuffer Fail");
			throw("d3d9Create indexBuffer Fail");
		}

		m_IndexCount = indexCount;
		m_size = presize*indexCount;
		return X_OK;


	}

	/*/----------------------------------------------

       vertex Declaration
	//-------------------------------------------------------*/
	xd3d9VertexDeclaration::xd3d9VertexDeclaration(LPDIRECT3DDEVICE9 pDevice)
		:xVertexDeclaration(),m_pd3d9device(pDevice),m_pd3d9decl(NULL)
	{

	}

	xd3d9VertexDeclaration::~xd3d9VertexDeclaration()
	{
		SafeRelease(m_pd3d9decl)

	}

	LPDIRECT3DVERTEXDECLARATION9 xd3d9VertexDeclaration::Getd3d9VertexDec() const 
	{
		if(m_pd3d9decl)
			return m_pd3d9decl;

		
		if(FAILED( m_pd3d9device->CreateVertexDeclaration(xD3D9Help::CastToD3DvertexElement9(this),&m_pd3d9decl)))
		{
			xLogMessager::getSingleton().logMessage("Create vertex declaration fail ");
			return NULL;
		}
		return m_pd3d9decl;

	}




	/*---------------------------------------------------------------------------
          HardBufferManager
	//-------------------------------------------------------------------------*/

	xd3d9HardBufferManager::xd3d9HardBufferManager(LPDIRECT3DDEVICE9 pDevice)
		:xHardBufferManager(),m_pDevice(pDevice)
	{
		assert(m_pDevice);

	}
	xd3d9HardBufferManager::~xd3d9HardBufferManager()
	{

	}


	xVertexHardBuffer* xd3d9HardBufferManager::CreateVertexHardBufferImplement(UINT vertexCount,UINT PreVertexSize,DWORD Usage)
	{
		return  new  xd3d9VertexBuffer(vertexCount,PreVertexSize,m_pDevice,Usage);

	}

	xIndexHardBuffer* xd3d9HardBufferManager::CreateIndexHardBufferImplement(UINT indexCount,xIndexHardBufferType indexType,DWORD Usage)
	{
		return  new xd3d9IndexBuffer(indexCount,indexType,m_pDevice,Usage);

	}

	  xVertexDeclaration* xd3d9HardBufferManager::CreateVertexDeclarationImplement()
	  {
		  return new xd3d9VertexDeclaration(m_pDevice);
	  }



}